#include "writingview.h"
#include <iostream>

WritingView::WritingView():editstatus(false),mydoc(0)
{
    //Create the Tree model:
    refTreeModel = Gtk::ListStore::create(columns);
    set_model(refTreeModel);

    //Add the TreeView's view columns:
    column.set_title("Writing");
    column.pack_start(cellrenderer);
    column.set_resizable(true);
    append_column(column);
    //append_column("Count",columns.count);
    column.set_cell_data_func(cellrenderer, sigc::mem_fun(*this, &WritingView::datarender) );
    cellrenderer.signal_edited().connect(sigc::mem_fun(*this, &WritingView::save) );
    set_headers_visible(false);

    signal_row_activated().connect(sigc::mem_fun(*this,&WritingView::select));
    signal_drag_data_received().connect(sigc::mem_fun(*this,&WritingView::drag_data_received) );
    std::vector<Gtk::TargetEntry> targets;
    targets.push_back( Gtk::TargetEntry("WRITING-ID") );
    drag_source_set(targets);
    targets.push_back( Gtk::TargetEntry("DOCUMENT-ID") );
    drag_dest_set(targets);
    enable_model_drag_dest(targets,Gdk::ACTION_ASK );
    get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);
    signal_drag_data_get().connect(sigc::mem_fun(*this,&WritingView::onDataGet));

    //Fill popup menu:
    {
        Gtk::Menu::MenuList& menulist = menuPopup.items();

        menulist.push_back( Gtk::Menu_Helpers::MenuElem("_Insert", sigc::mem_fun(*this, &WritingView::insert) ) );
        menulist.push_back( Gtk::Menu_Helpers::MenuElem("_Edit", sigc::mem_fun(*this, &WritingView::edit) ) );
        menulist.push_back( Gtk::Menu_Helpers::MenuElem("_Remove", sigc::mem_fun(*this, &WritingView::remove) ) );
        menulist.push_back( Gtk::Menu_Helpers::MenuElem("_Remove All", sigc::mem_fun(*this, &WritingView::remove_all) ) );
    }
    menuPopup.accelerate(*this);
}

WritingView::~WritingView()
{
}
void WritingView::set_documents(sdms::documents* doc)
{
    mydoc=doc;
}

void WritingView::update()
{
    if (!mydoc) return;
    std::vector<sdms::writing> t=mydoc->getwriting();
    refTreeModel->clear();
    for(int i=0; i<t.size(); i++)
    {
        Gtk::TreeModel::Row row = *(refTreeModel->append());
        row[columns.id] = t[i].id;
        row[columns.name] =  t[i].name;
        row[columns.count] =  t[i].count;
    }
}

//处理弹出菜单
bool WritingView::on_button_press_event(GdkEventButton* event)
{
    //Call base class, to allow normal handling,
    //such as allowing the row to be selected by the right-click:
    bool return_value = TreeView::on_button_press_event(event);

    //Then do our custom stuff:
    if( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) )
    {
        menuPopup.popup(event->button, event->time);
    }
    return return_value;
}

//插入专题
//切换到编辑状态
void WritingView::insert()
{
    //cellrenderer=0;
    if (!editstatus)
    {
        //remove_all_columns();
        //append_column_editable("Writing", columns.name);

        //让用户可以输入注释内容
        //append_column_editable("Comment", columns.comment);
        //如何确定当前鼠标点选的位置？
        Gtk::TreeModel::Row row = *(refTreeModel->append());//insert()?
        row[columns.name] = "New Writing...";
        Gtk::ListStore::Path path=refTreeModel->get_path(row);
        Gtk::TreeViewColumn* column=(get_column(0));
        cellrenderer.property_editable() = true;
        //cellrenderer=dynamic_cast <Gtk::CellRendererText*>(get_column_cell_renderer(0));
        //if (cellrenderer) cellrenderer->signal_edited().connect(sigc::mem_fun(*this, &WritingView::save) );
        set_cursor(path,*column,true);

        editstatus=true;
    }
    else
    {
        std::cout << "Please modify the new theme's name." << std::endl;
        //是否需要弹出窗口来进行提示？也可以显示到状态条上
    }
}

//保存当前编辑的主题
void WritingView::save(const Glib::ustring& path_string, const Glib::ustring& new_text)
{
    std::cout << "Test save function." << std::endl;
    Gtk::TreePath path(path_string);
    if (editstatus)
    {
        //Get the row from the path:
        Gtk::TreeModel::iterator iter = refTreeModel->get_iter(path);
        if(iter)
        {
            Gtk::TreeModel::Row row = *iter;
            sdms::writing w;
            w.name=new_text;
            w.id=row[columns.id];
            bool result=true;
            if (w.id)
            {
                //update writing table
                if (mydoc->update(&w))  row[columns.name] = new_text;
            }
            else
            {
                //new writing
                if(mydoc  && new_text!="New Writing..." && mydoc->add(&w))
                {
                    row[columns.name] = new_text;
                    row[columns.id]=w.id;
                }
                else
                    refTreeModel->erase(iter);
            }
            editstatus=false;
            cellrenderer.property_editable()=false;
        }
    }
}

void WritingView::edit()
{
    if (!editstatus)
    {
        std::cout << "Test edit function." << std::endl;
        Glib::RefPtr<Gtk::TreeView::Selection> refSelection = get_selection();
        if(refSelection)
        {
            std::list<Gtk::TreeModel::Path> selected = refSelection->get_selected_rows();
            Gtk::TreeModel::iterator iter = refTreeModel->get_iter(*(selected.begin()));
            if(iter)
            {
                Gtk::ListStore::Path path=refTreeModel->get_path(iter);
                Gtk::TreeViewColumn* column=(get_column(0));
                cellrenderer.property_editable()=true;
                editstatus=true;
                set_cursor(path,*column,true);
            }
        }
    }
}

//删除一个主题，对应主题下的所有文档信息也将删除，弹出对话框请用户确认
void WritingView::remove()
{
    Glib::RefPtr<Gtk::TreeView::Selection> refSelection = get_selection();
    if(refSelection)
    {
        std::list<Gtk::TreeModel::Path> selected = refSelection->get_selected_rows();
        Gtk::TreeModel::iterator iter = refTreeModel->get_iter(*(selected.begin()));
        if(iter)
        {
            Gtk::MessageDialog dialog("Are you sure to delete this writing?", false, Gtk::MESSAGE_QUESTION,Gtk::BUTTONS_OK_CANCEL,true);
            int result=dialog.run();
            if (result==Gtk::RESPONSE_OK )
            {
                sdms::writing w;
                w.id=(*iter)[columns.id];
                //theme.name=(*iter)[columns.name];
                mydoc->del(&w);
                refTreeModel->erase(iter);
            }
        }
    }
}

//删除所有主题
void WritingView::remove_all()
{
    Gtk::MessageDialog dialog("Are you sure to delete all writings?", false, Gtk::MESSAGE_QUESTION,Gtk::BUTTONS_OK_CANCEL,true);
    int result=dialog.run();
    if (result==Gtk::RESPONSE_OK )
    {
        sdms::writing w;
        mydoc->del(&w);
        refTreeModel->clear();
    }
}
void WritingView::datarender(Gtk::CellRenderer* /* renderer */, const Gtk::TreeModel::iterator& iter)
{
    //Get the value from the model and show it appropriately in the view:
    if(iter)
    {
        Gtk::TreeModel::Row row = *iter;
        //std::string model_value = row[columns.name];
        cellrenderer.property_text() = row[columns.name];
    }
}

//处理专题的选择
//todo: 调用主界面的窗口，增加过滤器
void WritingView::select(const Gtk::ListStore::Path& path, Gtk::TreeViewColumn* column)
{
    //std::cout << "Test select function." << std::endl;
    Glib::RefPtr<Gtk::TreeView::Selection> refSelection = get_selection();
    if(refSelection)
    {
        std::list<Gtk::TreeModel::Path> selected = refSelection->get_selected_rows();
        //双击或回车应该只有一个要素
        //for(std::list<Gtk::TreeModel::Path>::iterator i=selected.begin();i!=selected.end();i++)
        Gtk::TreeModel::iterator iter = refTreeModel->get_iter(*(selected.begin()));
        if(iter && filterview)
        {
            sdms::WritingFilter tf;
            tf.set_documents(mydoc);
            tf.set_id((*iter)[columns.id]);
            tf.eval();
            Glib::ustring name=(*iter)[columns.name];
            tf.set_name(name);
            filterview->clear();
            filterview->add(tf);
            //docview->update(&tf);
        }
    }
}

void WritingView::drag_data_received(const Glib::RefPtr<Gdk::DragContext>& context, int x, int y,
                                     const Gtk::SelectionData& selection_data, guint, guint time)
{
    if (selection_data.get_data_type()=="DOCUMENT-ID")//接收docview的DND信息
    {
        std::string sel=selection_data.get_data_as_string();
        Gtk::TreeModel::Path path;
        Gtk::TreeViewDropPosition 	 pos;
        get_dest_row_at_pos(x,y,path,pos);
        Gtk::TreeModel::iterator  iter = refTreeModel->get_iter(path);
        std::vector<std::string> singledoc=utils::explode(sel,",");
        sdms::writing t;
        t.id=(*iter)[columns.id];
        for (int i=0; i<singledoc.size(); i++)
        {
            sdms::document d;
            d.id=utils::fromString<int>(singledoc[i]);
            if (mydoc->update(&t,&d))  (*iter)[columns.count]=t.count;
        }
    }
    context->drag_finish(false, false, time);
}
void WritingView::set_docview(DocView* dv)
{
    docview=dv;
}
void WritingView::set_filterview(FilterView* fv)
{
    filterview=fv;
}
void WritingView::onDataGet(const Glib::RefPtr<Gdk::DragContext>&,   Gtk::SelectionData& selection_data, guint, guint)
{
    std::string id;
    Glib::RefPtr<Gtk::TreeView::Selection> refSelection = get_selection();
    if(refSelection)
    {
        std::list<Gtk::TreeModel::Path> selected = refSelection->get_selected_rows();
        //默认的多选拖动行为不够友好
        //是否需要自己进一步处理？
        //std::cout<<selected.size()<<std::endl;
        for(std::list<Gtk::TreeModel::Path>::iterator i=selected.begin(); i!=selected.end(); i++)
        {
            Gtk::TreeModel::iterator iter = refTreeModel->get_iter(*i);
            Gtk::TreeModel::Row row = *iter;
            if (i!=selected.begin()) id+=",";
            id+=utils::toString(row[columns.id]);
        }
    }
    selection_data.set(selection_data.get_target(), 8 /* 8 bits format */,
                       (const guchar*)id.c_str(),id.size());
}
